import 'reflect-metadata';
import { container } from '../src/infrastructure/ioc/container';
import { TYPES } from '../src/infrastructure/ioc/types';
import { IAuthService } from '../src/application/interfaces/IAuthService';
import { IUserService } from '../src/application/interfaces/IUserService';
import { LoggerService } from '../src/infrastructure/logging/logger.service';
import { DataSource } from 'typeorm';

// 测试函数：测试用户注册、登录和权限验证
async function testAuth() {
  try {
    // 获取所需服务
    const authService = container.get<IAuthService>(TYPES.AuthService);
    const userService = container.get<IUserService>(TYPES.UserService);
    const logger = container.get<LoggerService>(TYPES.LoggerService);
    const dataSource = container.get<DataSource>(TYPES.DataSource);

    // 初始化数据库
    await dataSource.initialize();
    logger.info('数据库已初始化');

    // 1. 测试用户注册
    console.log('===== 测试用户注册 =====');
    try {
      const newUser = await authService.register('testuser', 'password123', 'test@example.com');
      console.log('用户注册成功:', newUser);
    } catch (error: any) {
      console.error('用户注册失败:', error.message);
    }

    // 2. 测试重复用户名注册
    console.log('\n===== 测试重复用户名注册 =====');
    try {
      await authService.register('testuser', 'password456', 'another@example.com');
      console.log('重复用户名注册成功 (预期应该失败)');
    } catch (error: any) {
      console.log('重复用户名注册失败 (符合预期):', error.message);
    }

    // 3. 测试用户登录 - 正确密码
    console.log('\n===== 测试用户登录 - 正确密码 =====');
    try {
      const loginResult = await authService.login('testuser', 'password123');
      console.log('用户登录成功:', {
        userId: loginResult.user.id,
        username: loginResult.user.username,
        role: loginResult.user.role,
        accessToken: loginResult.accessToken.substring(0, 20) + '...',
        refreshToken: loginResult.refreshToken.substring(0, 20) + '...'
      });

      // 保存 token 用于后续测试
      const token = loginResult.accessToken;

      // 4. 测试 token 验证
      console.log('\n===== 测试 token 验证 =====');
      const verifiedUser = await authService.verifyToken(token);
      if (verifiedUser) {
        console.log('Token 验证成功:', {
          userId: verifiedUser.id,
          username: verifiedUser.username
        });
      } else {
        console.log('Token 验证失败');
      }

      // 5. 测试权限验证
      console.log('\n===== 测试基本权限验证 =====');
      const hasPermission = authService.validatePermission(loginResult.user, 'read:messages');
      console.log(`用户是否拥有 'read:messages' 权限: ${hasPermission} (预期为 false，因为新用户没有权限)`);

      // 6. 测试授予权限
      console.log('\n===== 测试授予权限 =====');
      const userWithPermission = await userService.grantPermissions(loginResult.user.id, ['read:messages', 'write:messages']);
      console.log('已授予权限:', userWithPermission.permissions);

      // 7. 再次测试权限验证
      console.log('\n===== 授予权限后再次测试 =====');
      const hasPermissionNow = authService.validatePermission(userWithPermission, 'read:messages');
      console.log(`用户现在是否拥有 'read:messages' 权限: ${hasPermissionNow} (预期为 true)`);

      // 8. 测试多权限验证
      console.log('\n===== 测试多权限验证 =====');
      const hasMultiplePermissions = authService.validatePermission(userWithPermission, ['read:messages', 'write:messages']);
      console.log(`用户是否同时拥有 'read:messages' 和 'write:messages' 权限: ${hasMultiplePermissions} (预期为 true)`);

      // 9. 测试角色提升
      console.log('\n===== 测试角色提升 =====');
      const admin = await userService.assignRole(loginResult.user.id, 'admin');
      console.log(`用户角色已更改为: ${admin.role}`);

      // 10. 测试管理员权限
      console.log('\n===== 测试管理员权限 =====');
      const adminHasPermission = authService.validatePermission(admin, 'any:permission');
      console.log(`管理员是否拥有任意权限: ${adminHasPermission} (预期为 true，因为管理员拥有所有权限)`);

      // 11. 测试刷新令牌
      console.log('\n===== 测试刷新令牌 =====');
      const refreshResult = await authService.refreshToken(loginResult.refreshToken);
      if (refreshResult) {
        console.log('令牌刷新成功:', {
          newAccessToken: refreshResult.accessToken.substring(0, 20) + '...',
          newRefreshToken: refreshResult.refreshToken.substring(0, 20) + '...'
        });
      } else {
        console.log('令牌刷新失败');
      }

      // 12. 测试修改密码
      console.log('\n===== 测试修改密码 =====');
      const passwordChanged = await authService.changePassword(loginResult.user.id, 'password123', 'newpassword123');
      console.log(`密码修改成功: ${passwordChanged}`);

      // 13. 使用旧密码登录
      console.log('\n===== 使用旧密码登录 =====');
      try {
        await authService.login('testuser', 'password123');
        console.log('使用旧密码登录成功 (预期应该失败)');
      } catch (error: any) {
        console.log('使用旧密码登录失败 (符合预期):', error.message);
      }

      // 14. 使用新密码登录
      console.log('\n===== 使用新密码登录 =====');
      try {
        const newLoginResult = await authService.login('testuser', 'newpassword123');
        console.log('使用新密码登录成功:', newLoginResult.user.username);
      } catch (error: any) {
        console.log('使用新密码登录失败:', error.message);
      }

    } catch (error: any) {
      console.error('登录测试失败:', error.message);
    }

  } catch (error: any) {
    console.error('测试过程出错:', error);
  } finally {
    // 关闭数据库连接
    const dataSource = container.get<DataSource>(TYPES.DataSource);
    if (dataSource.isInitialized) {
      await dataSource.destroy();
      console.log('\n数据库连接已关闭');
    }
  }
}

// 运行测试
testAuth().catch(console.error); 